<!--
(C) 2020 URD

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

<!-- urd-ac-3ch-node Config Node の記述 -->
<script type="text/html" data-template-name="URD AC 3ch sensor">

    <!-- Name -->
    <div class="form-row">
        <label for="node-config-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></span></label>
        <input type="text" id="node-config-input-name" data-i18n="[placeholder]node-red:common.label.name">
    </div>

    <!-- Sensor ID -->
    <div class="form-row">
        <label for="node-config-input-sensorId"><i class="fa fa-flag"></i> <span data-i18n="serial.label.sensorId"></span></label>
        <input type="text" id="node-config-input-sensorId" data-i18n="[placeholder]serial.placeholder.sensorId">
    </div>

    <!-- Title of contentData. -->
    <div class="form-row" style="margin-bottom:0;">
        <label><i class="fa fa-list"></i> <span data-i18n="urdDataItem.label.itemNo" /></label>
    </div>
    <!-- List of contentData. -->
    <div>
        <ol id="content_data">
            <!-- Insert $rowTemplate -->
        </ol>
    </div>
</script>

<script type="text/html" data-help-name="URD AC 3ch sensor" charset="utf-8">
    <p>Configure the 3ch current sensor.</p>
    <p>Set the ID of the sensor, each CT parts, data names, and units of measurement targets.</p>
    <p>Each CT parts of the sensor have default measurement magnifications.</p>
    <p>The magnification of 10 mm to 24 mm diameter CT parts are 400, and 36 mm diameter CT parts are 700.</p>
    <p>To set a optional magnification, set the CT part to "Customize magnification" and input the magnification.</p>
    <p>When the data which has an channel without CT part is recieved, measured value(dataValue) of the channel is set to 9999.99.</p>
    <p>Excluding the channel from sending data is required, set the CT part to "unconnected".</p>    
</script>

<script type="text/javascript">

// To avoids polluting the global namespace.
(() => {
    RED.nodes.registerType('URD AC 3ch sensor', {
        // Node-RED node definition.
        category: 'config',
        defaults: {
            name: { value: 'ac-3ch-Sensor' },
            sensorId: { value: '', required: true },
            configObject: { value: '' },
            // --------------------
            range: { value: '' }, // DO NOT USE THIS, It's just for backward compatible. Remove this in the future.
            clampType0: { value: '' }, // DO NOT USE THIS, It's just for backward compatible. Remove this in the future.
            clampType1: { value: '' }, // DO NOT USE THIS, It's just for backward compatible. Remove this in the future.
            clampType2: { value: '' }, // DO NOT USE THIS, It's just for backward compatible. Remove this in the future.
            // --------------------
        },
        label() { return this.name || 'ac-3ch-Sensor' },
        oneditprepare() {
            const node = this;

            // User definition.
            const CLAMP_TYPE_CUSTOM = 'custom';
            const CLAMP_TYPE_UNCONNECTED = 'unconnected';
            const clampTypes = [
                { value: 'WLS50', label: 'CTT-10-CLS-WLS50(400x)'}, // , rangeInput: '400'},
                { value: 'WLS100', label: 'CTT-16-CLS-WLS100(400x)'}, // , rangeInput: '400'},
                { value: 'WLS250', label: 'CTT-24-CLS-WLS250(400x)'}, // , rangeInput: '400'},
                { value: 'WLS600', label: 'CTT-36-CLS-WLS600(700x)'}, // , rangeInput: '700'},
                { value: CLAMP_TYPE_CUSTOM, label: node._('urdDataItem.clamp.custom')}, // , rangeInput: undefined},
                { value: CLAMP_TYPE_UNCONNECTED, label: node._('urdDataItem.clamp.unconnect')}, // , rangeInput: undefined},
            ];

            const handleRowInputs = ($select) => {
                // const $this = $(this);
                const $rowInputs = $select.closest('div.row').find('select, input');

                switch ($select.val()) {
                    case CLAMP_TYPE_CUSTOM: // 「カスタム」選択時、入力欄を有効 & range入力必須
                        $rowInputs.prop({ disabled: false });
                        $select.siblings('.range-input').prop({ required: true });
                        break;
                    case CLAMP_TYPE_UNCONNECTED: // 「未接続」選択時、入力欄を無効化 & range入力必須解除 (自身以外を入力無効・必須解除)
                        $rowInputs.not($select).prop({ disabled: true, required: false });
                        break;
                    default: // 上記以外を選択時、入力欄を無効化 & range必須解除
                        $rowInputs.prop({ disabled: false });
                        $select.siblings('.range-input').prop({ disabled: true, required: false });
                }
            };

            // Define editableList.
            $('#content_data').css('min-height', '500px').css('min-width', '400px').editableList({
                addButton: false,
                sortable: false,
                removable: false,
                // Process when click add button.
                addItem($row, index, data) {
                    // Labels
                    const labelCt = node._('urdDataItem.label.ct');
                    const labelPlaceholderNumeric = node._('urdDataItem.placeholder.numeric');
                    const labelDataName = node._('urdDataItem.label.dataName');
                    const labelUnit = node._('urdDataItem.label.unit');

                    const rangeInput = data.rangeInput || '';
                    const dataName = data.dataName || '';
                    const unit = data.unit || '';

                    // A row template.
                    const $rowTemplate = $(`
                        <div class="row">
                            <!-- CT selectbox -->
                            <div class="form-row">
                                <label><i class="fa fa-tag"></i> ${labelCt}</label>
                                <select class="clamp-type"> 
                                    <!-- Insert $clampTypeOptions here. -->
                                </select>
                                <input type="text" class="range-input" style="width:80px;" value="${rangeInput}" placeholder="${labelPlaceholderNumeric}" pattern="^[-]?([1-9]\\d*|0)(\\.\\d+)?$">
                            </div>
                            <!-- dataName -->
                            <div class="form-row">
                                <label><i class="fa fa-tag"></i> ${labelDataName}</label>
                                <input type="text" class="data-name" value="${dataName}">
                            </div>
                            <!-- unit -->
                            <div class="form-row">
                                <label><i class="fa fa-tag"></i> ${labelUnit}</label>
                                <input type="text" class="unit" style="width: 100px;" value="${unit}">
                            </div>
                        </div>
                    `);

                    const $clampTypeSelect = $rowTemplate.find('select.clamp-type');
                    $clampTypeSelect.append(clampTypes.map((ct) => {
                        // https://qiita.com/QUANON/items/5822f805d558ad078db3
                        const selected = (data.clampType === ct.value);
                        return $('<option>').val(ct.value).text(ct.label).prop('selected', selected);
                    }));
                    // Tigger onchange event.
                    handleRowInputs($clampTypeSelect);

                    // Append row.
                    $rowTemplate.appendTo($row);
                },
            });

            // Events
            $('#content_data').on('change', '.clamp-type', function() {
                handleRowInputs($(this));
            });
            $('#content_data').on('blur', '.range-input', function () {
                // Erase invalid custom range-input.
                const $this = $(this);
                if (Number.isNaN(Number($this.val()))) {
                    $this.val('');
                }
            });

            // Default values for each row.
            const dataNamesDefault = JSON.parse(node._('urdDataItem.input.dataNames'));
            const unitDefault = 'A'; // node._('urdDataItem.value.default.unit');
            const defaultRows = dataNamesDefault.map(dataName => ({ clampType: 'WLS50', rangeInput: '', dataName, unit: unitDefault }));

            // Stack rows.
            let configObject;
            if (typeof this.configObject === 'string') {
                // --------------------
                // configObject may be old version. This section is for backward compatible. Remove this seciton in the future.
                debugger;
                const cf = JSON.parse(this.configObject);
                const old_ct = [ this.clampType0, this.clampType1, this.clampType2 ].map(e => (e === 'unconnect' ? 'unconnected': e));
                const old_rg = JSON.parse(this.range).map((e, i) => (old_ct[i] === 'custom' ? e : ''));
                configObject = cf.map((j, i) => ({ clampType: old_ct[i], dataName: j.dataName, rangeInput: old_rg[i], unit: j.unit }));
                // --------------------
            } else {
                configObject = this.configObject || defaultRows;
            }
            // configObject = [ // It's just a test code.
            //     { clampType: 'WLS600', rangeInput: '', dataName: 'd1', unit: unitDefault },
            //     { clampType: 'custom', rangeInput: '8', dataName: 'd2', unit: unitDefault },
            //     { clampType: 'unconnected', rangeInput: '', dataName: 'd3', unit: unitDefault },
            // ];
            $('#content_data').editableList('addItems', configObject);
        },
        oneditsave() {
            const editableItems = $('#content_data').editableList('items');

            this.configObject = Array.from(editableItems).map(($item) => {
                const clampType = $item.find('.clamp-type').val();
                return {
                    clampType,
                    rangeInput: (clampType === 'custom' ? $item.find('.range-input').val() : undefined),
                    dataName: $item.find('.data-name').val(),
                    unit: $item.find('.unit').val(),
                };
            });
            // --------------------
            // This section is for backward compatible. Remove this seciton in the future.
            this.range = undefined;
            this.clampType0 = undefined;
            this.clampType1 = undefined;
            this.clampType2 = undefined;
            // --------------------
        },
    });
})();

</script>
